package com.csaba.swing.gui.login;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import com.csaba.connector.BankServiceFactory;
import com.csaba.connector.ServiceException;
import com.csaba.connector.model.Bank;
import com.csaba.connector.model.Customer;
import com.csaba.connector.model.Session;
import com.csaba.connector.service.LoginService;
import com.csaba.swing.MainWindow;
import com.csaba.swing.action.ServiceRunner;
import com.csaba.swing.gui.GUIContext;
import com.csaba.swing.gui.wizard.WizardPage;
import com.csaba.swing.model.Config;
import com.csaba.util.LoggerHelper;

@SuppressWarnings( "serial" )
public abstract class AbstractLoginPage extends WizardPage
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();

	public static final String CP_SAVED_DETAILS = "savedDetails"; //$NON-NLS-1$

	protected boolean doLogin( Customer customer )
	{
		final Bank bank = ( (LoginWizardModel) context.getWizardModel() ).getBank();

		if ( customer == null )
		{
			return false;
		}

		//verify whether the session is already active or not
		final List<Session> sessions = GUIContext.getInstance().getSessions();
		for ( final Session session : sessions )
		{
			if ( session.getBank().equals(bank) && session.getCustomer().getLoginId().equals(customer.getLoginId()) )
			{
				JOptionPane.showMessageDialog(context.getDialog().getOwner(), MainWindow.getString(
						"AbstractLoginPage.msg.alreadyOpen", customer.getLoginId(), bank.getName())); //$NON-NLS-1$
				return false;
			}
		}

		Session session = null;
		try
		{
			final LoginService login = BankServiceFactory.getBankService(bank, LoginService.class);
			login.setCustomer(customer);

			new ServiceRunner(null, login, MainWindow.getString("AbstractLoginPage.msg.loginProgress", bank)).execute(); //$NON-NLS-1$

			session = login.getSession();

			//update customer object as it is usually a different bank specific instance at the end of the login.
			customer = session.getCustomer();

		}
		catch ( final ServiceException se )
		{
			logger.log(Level.SEVERE, "Cannot authenticate user.", se); //$NON-NLS-1$
			JOptionPane.showMessageDialog(context.getDialog().getOwner(), se.getMessage() + "\n" //$NON-NLS-1$
					+ se.getNativeMessage(),
					MainWindow.getString("AbstractLoginPage.titleError"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$
			return false;
		}
		catch ( final Exception e )
		{
			logger.log(Level.SEVERE, "Cannot authenticate user.", e); //$NON-NLS-1$
			JOptionPane.showMessageDialog(context.getDialog().getOwner(), MainWindow
					.getString("AbstractLoginPage.msg.loginFailed") + e.getMessage(), //$NON-NLS-1$
					MainWindow.getString("AbstractLoginPage.titleError"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$
			return false;
		}

		GUIContext.getInstance().addSession(session);

		//save last login info if necessary
		if ( ( (LoginWizardModel) context.getWizardModel() ).isSaveDetails() )
		{
			try
			{
				final LoginDetails details = getDetailsToSave(customer);
				if ( details != null )
					LoginDetails.store(details);
				Config.saveConfig();
			}
			catch ( final Exception ex )
			{
				logger.log(Level.SEVERE, "Error during saving the config file.", ex); //$NON-NLS-1$
				JOptionPane
						.showMessageDialog(
								context.getDialog().getOwner(),
								MainWindow.getString("AbstractLoginPage.msg.saveConfig") + ex.getMessage(), MainWindow.getString("AbstractLoginPage.titleWarning"), //$NON-NLS-1$ //$NON-NLS-2$
								JOptionPane.WARNING_MESSAGE);
			}
		}

		return true;
	}

	@Override
	public void updateView()
	{
		//check out for saved details
		final LoginDetails details = (LoginDetails) context.getProperty(CP_SAVED_DETAILS);
		if ( details != null )
		{
			setSavedDetails(details);
		}

		super.updateView();
	}

	protected abstract LoginDetails getDetailsToSave( Customer customer );

	protected abstract void setSavedDetails( LoginDetails details );
}
